const csv = require('csvtojson');
const http = require('http');
const fs = require('fs');
const fnv = require('fnv-plus');

function File() {
    const bill_file = csv()
        .fromFile('./bill.csv')
        .then((json) => {
            return json;
        })
    const categories_file = csv()
        .fromFile('./categories.csv')
        .then((json) => {
            return json;
        })
    return Promise.all([bill_file, categories_file])
};


http.createServer((req, res) => { // 创建服务，生成实例
    const path = req.url.split('?')[0];

    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

    const { method } = req;
    if (method === 'OPTIONS') {
        res.writeHead(200, {
            'Content-Type': 'text/plain',
            'Access-Control-Allow-Headers': 'Content-Type, Accept',
        });

        res.end('');

        return;
    };

    switch (path) {
        case '/add':
            add(res, req);
            break;
        default:
            getData(res);
    };

}).listen('8088');

function add(res, req) {

    let alldata = '';

    let pormise = new Promise((resolve, reject) => {
        req.on('data', (e) => {
            alldata += e

            resolve(JSON.parse(alldata));
        });
    });

    pormise.then(result => {

        // result
        /**
         * @param time 账单时间
         * @param type  0 支出 1 收入
         * @param amount 金额
         * @param category 详细分类名称
         */
        const { time, type, amount, category } = result;

        // 判断文件是否写入成功
        let flag, category_flag;

        // 判断输入的二次分类项目是否已存在
        const { _categories } = global;
        const bool = _categories?.[category] || false;
        const hash = bool || fnv.hash(new Date().getTime() + amount, 64).str();

        res.writeHead(200, {
            'Content-Type': 'text/plain; charset=utf-8',
            'Access-Control-Allow-Headers': 'Content-Type, Accept'
        });

        fs.appendFile(
            './bill.csv',
            '\r\n' +
            type + ',' +
            time + ',' +
            hash + ',' +
            amount,
            (err) => {
                res.write(JSON.stringify({ msg: 'faild', status: false }));
                res.end();

                flag = true;
            });

        if (category) {
            // 存在不用写入新的类别值
            bool || fs.appendFile(
                './categories.csv',
                '\r\n' +
                hash + ',' +
                type + ',' +
                category,
                (err) => {
                    res.write(JSON.stringify({ msg: 'faild', status: false }));
                    res.end();

                    category_flag = true;
                });
        }

        // 没有二次分类
        if (!flag && !category) {
            res.write(JSON.stringify({ msg: 'success', status: true }));
            res.end();
        };

        // 是二次分类 且 传入的不为空  且 如果存在为true或写入成功
        if (!flag && category && (bool || !category_flag)) {
            res.write(JSON.stringify({ msg: 'success', status: true }));
            res.end();
        };
    }).finally(() => {
        // 更新类别的值
        csv()
            .fromFile('./categories.csv')
            .then((json) => {
                return json;
            }).then(result => {
                global._categories = _map(result);
            });
    })
};

function getData(res) {
    File().then(result => {

        global._categories = _map(result);

        // 解决乱码
        res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
        res.write(JSON.stringify(result));
        res.end();
    });
};

// 保存读取的数据,以键值的方式存储

function _map(result) {
    const categories = {};
    for (let T of result?.[1]) {
        categories[T.name] = T.id;
    };

    return categories;
}